//========================================================= 
/**@file Runable
 * @brief 
 * 
 * @date 25-07-17   14:55:28
 * @author Zhyioo 
 * @version 1.0
 */ 
//--------------------------------------------------------- 
#ifndef _LIBZHOUYB_RUNABLE_H_
#define _LIBZHOUYB_RUNABLE_H_
//--------------------------------------------------------- 
#include "../../include/Base.h"
//--------------------------------------------------------- 
namespace zhou_yb {
namespace application {
namespace tools {
//--------------------------------------------------------- 
class Runable
{
protected:
    /// 是否处于运行中
    bool _is_running;
public:
    //----------------------------------------------------- 
    /// 固定帧间隔
    uint FixedUpdateIntervalMs;
    /// 空闲Update的最大次数
    uint UpdateMaxIdleCount;
    /// 是否允许Update间进行休眠
    bool IsAllowUpdateSleep;
    //----------------------------------------------------- 
public:
    //----------------------------------------------------- 
    virtual bool Update(Timer::TickType tick) = 0;
    virtual bool FixedUpdate(Timer::TickType tick, uint delta) = 0;
    //----------------------------------------------------- 
public:
    //----------------------------------------------------- 
    Runable() : _is_running(false), FixedUpdateIntervalMs(33), UpdateMaxIdleCount(100), IsAllowUpdateSleep(false) {}
    //----------------------------------------------------- 
    /// 返回是否需要继续运行
    virtual bool IsRunning() const
    {
        return _is_running;
    }
    //----------------------------------------------------- 
    uint Run(uint duration = 0)
    {
        const uint MIN_WAIT_TIME_MS = 10;

        Timer::TickType last_tick = Timer::TimeTick();
        Timer::TickType fixed_start_tick = last_tick;
        uint fixed_count = 0;
        Timer::TickType exit_tick = last_tick + duration;
        _is_running = true;
        while (IsRunning())
        {
            Timer::TickType tick = Timer::TimeTick();
            for (uint i = 0; i < UpdateMaxIdleCount; ++i)
            {
                if (Update(tick))
                    break;
            }
            uint delta = tick - last_tick;
            if (delta < FixedUpdateIntervalMs)
            {
                // 休眠的最小粒度
                if (IsAllowUpdateSleep && ((FixedUpdateIntervalMs - delta) > MIN_WAIT_TIME_MS))
                {
                    Timer::Wait(MIN_WAIT_TIME_MS);
                }
                continue;
            }
            FixedUpdate(tick, delta);
            ++fixed_count;
            last_tick = tick;

            if (duration && exit_tick < tick)
            {
                _is_running = false;
                break;
            }
        }
        if (fixed_count > 0)
        {
            uint fps = (Timer::TimeTick() - fixed_start_tick) / fixed_count;
            return fps;
        }
        return 0;
    }
    //----------------------------------------------------- 
    /**
     * @brief 停止
     * @date 2025-07-17 15:06
     */
    virtual void Stop()
    {
        _is_running = false;
    }
    //----------------------------------------------------- 
};
//--------------------------------------------------------- 
} // namespace tools
} // namespace application
} // namespace zhou_yb
//--------------------------------------------------------- 
 //--------------------------------------------------------- 
 #endif // #ifndef _LIBZHOUYB_RUNABLE_H_
//========================================================= 